using Lzfy_His_Service.Models;
using Lzfy_His_Service.Repositories;

namespace Lzfy_His_Service.Services
{
    /// <summary>
    /// 退款审核工作记录服务实现
    /// </summary>
    public class RefundAcctService : IRefundAcctService
    {
        private readonly IRefundAcctRepository _refundAcctRepository;
        private readonly ILogger<RefundAcctService> _logger;

        public RefundAcctService(
            IRefundAcctRepository refundAcctRepository,
            ILogger<RefundAcctService> logger)
        {
            _refundAcctRepository = refundAcctRepository;
            _logger = logger;
        }

        /// <summary>
        /// 根据ID获取退款审核工作记录
        /// </summary>
        public async Task<RefundAcctResponse?> GetByIdAsync(int id)
        {
            try
            {
                var refundAcct = await _refundAcctRepository.GetByIdAsync(id);
                return refundAcct != null ? MapToResponse(refundAcct) : null;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取退款审核工作记录失败，ID: {Id}", id);
                throw;
            }
        }

        /// <summary>
        /// 根据结算ID获取退款审核工作记录
        /// </summary>
        public async Task<RefundAcctResponse?> GetByAcctIdAsync(string acctId)
        {
            try
            {
                var refundAcct = await _refundAcctRepository.GetByAcctIdAsync(acctId);
                return refundAcct != null ? MapToResponse(refundAcct) : null;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "根据结算ID获取退款审核工作记录失败，AcctId: {AcctId}", acctId);
                throw;
            }
        }

        /// <summary>
        /// 根据用户名获取退款审核工作记录列表
        /// </summary>
        public async Task<IEnumerable<RefundAcctResponse>> GetByUsernameAsync(string username)
        {
            try
            {
                var refundAccts = await _refundAcctRepository.GetByUsernameAsync(username);
                return refundAccts.Select(MapToResponse);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "根据用户名获取退款审核工作记录失败，Username: {Username}", username);
                throw;
            }
        }

        /// <summary>
        /// 获取所有退款审核工作记录
        /// </summary>
        public async Task<IEnumerable<RefundAcctResponse>> GetAllAsync()
        {
            try
            {
                var refundAccts = await _refundAcctRepository.GetAllAsync();
                return refundAccts.Select(MapToResponse);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取所有退款审核工作记录失败");
                throw;
            }
        }

        /// <summary>
        /// 分页获取退款审核工作记录
        /// </summary>
        public async Task<(IEnumerable<RefundAcctResponse> Items, int TotalCount)> GetPagedAsync(
            int pageNumber, 
            int pageSize, 
            string? username = null, 
            string? acctId = null, 
            DateTime? startDate = null, 
            DateTime? endDate = null)
        {
            try
            {
                var (items, totalCount) = await _refundAcctRepository.GetPagedAsync(
                    pageNumber, pageSize, username, acctId, startDate, endDate);
                
                var responseItems = items.Select(MapToResponse);
                return (responseItems, totalCount);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "分页获取退款审核工作记录失败，页码: {PageNumber}, 页大小: {PageSize}", pageNumber, pageSize);
                throw;
            }
        }

        /// <summary>
        /// 创建退款审核工作记录
        /// </summary>
        public async Task<RefundAcctResponse> CreateAsync(RefundAcctCreateRequest request)
        {
            try
            {
                // 检查结算ID是否已存在
                var exists = await _refundAcctRepository.ExistsAsync(request.AcctId);
                if (exists)
                {
                    throw new InvalidOperationException($"结算ID {request.AcctId} 已存在");
                }

                var refundAcct = new RefundAcct
                {
                    Username = request.Username,
                    FullName = request.FullName,
                    AcctId = request.AcctId,
                    RefundBalanceSum = request.RefundBalanceSum
                };

                var id = await _refundAcctRepository.CreateAsync(refundAcct);
                refundAcct.Id = id;

                _logger.LogInformation("创建退款审核工作记录成功，ID: {Id}, AcctId: {AcctId}", id, request.AcctId);
                return MapToResponse(refundAcct);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建退款审核工作记录失败，AcctId: {AcctId}", request.AcctId);
                throw;
            }
        }

        /// <summary>
        /// 更新退款审核工作记录
        /// </summary>
        public async Task<RefundAcctResponse?> UpdateAsync(RefundAcctUpdateRequest request)
        {
            try
            {
                // 检查记录是否存在
                var existingRecord = await _refundAcctRepository.GetByIdAsync(request.Id);
                if (existingRecord == null)
                {
                    return null;
                }

                // 如果结算ID发生变化，检查新的结算ID是否已存在
                if (existingRecord.AcctId != request.AcctId)
                {
                    var acctIdExists = await _refundAcctRepository.ExistsAsync(request.AcctId);
                    if (acctIdExists)
                    {
                        throw new InvalidOperationException($"结算ID {request.AcctId} 已存在");
                    }
                }

                var refundAcct = new RefundAcct
                {
                    Id = request.Id,
                    InputDate = existingRecord.InputDate, // 保持原有的创建时间
                    Username = request.Username,
                    FullName = request.FullName,
                    AcctId = request.AcctId,
                    RefundBalanceSum = request.RefundBalanceSum
                };

                var success = await _refundAcctRepository.UpdateAsync(refundAcct);
                if (!success)
                {
                    return null;
                }

                _logger.LogInformation("更新退款审核工作记录成功，ID: {Id}, AcctId: {AcctId}", request.Id, request.AcctId);
                return MapToResponse(refundAcct);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新退款审核工作记录失败，ID: {Id}", request.Id);
                throw;
            }
        }

        /// <summary>
        /// 删除退款审核工作记录
        /// </summary>
        public async Task<bool> DeleteAsync(int id)
        {
            try
            {
                var success = await _refundAcctRepository.DeleteAsync(id);
                if (success)
                {
                    _logger.LogInformation("删除退款审核工作记录成功，ID: {Id}", id);
                }
                return success;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除退款审核工作记录失败，ID: {Id}", id);
                throw;
            }
        }

        /// <summary>
        /// 检查结算ID是否存在
        /// </summary>
        public async Task<bool> ExistsAsync(string acctId)
        {
            try
            {
                return await _refundAcctRepository.ExistsAsync(acctId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查结算ID是否存在失败，AcctId: {AcctId}", acctId);
                throw;
            }
        }

        /// <summary>
        /// 获取用户的退款审核工作统计信息
        /// </summary>
        public async Task<(int TotalCount, decimal TotalAmount)> GetUserStatisticsAsync(
            string username, 
            DateTime? startDate = null, 
            DateTime? endDate = null)
        {
            try
            {
                return await _refundAcctRepository.GetUserStatisticsAsync(username, startDate, endDate);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取用户统计信息失败，Username: {Username}", username);
                throw;
            }
        }

        /// <summary>
        /// 批量创建退款审核工作记录
        /// </summary>
        public async Task<IEnumerable<RefundAcctResponse>> BatchCreateAsync(IEnumerable<RefundAcctCreateRequest> requests)
        {
            try
            {
                var responses = new List<RefundAcctResponse>();
                
                foreach (var request in requests)
                {
                    var response = await CreateAsync(request);
                    responses.Add(response);
                }
                
                _logger.LogInformation("批量创建退款审核工作记录成功，数量: {Count}", responses.Count);
                return responses;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量创建退款审核工作记录失败");
                throw;
            }
        }

        /// <summary>
        /// 根据日期范围获取统计报表
        /// </summary>
        public async Task<object> GetStatisticsReportAsync(DateTime startDate, DateTime endDate)
        {
            try
            {
                var (items, _) = await _refundAcctRepository.GetPagedAsync(
                    1, int.MaxValue, null, null, startDate, endDate);
                
                var report = new
                {
                    DateRange = new { StartDate = startDate, EndDate = endDate },
                    TotalRecords = items.Count(),
                    TotalAmount = items.Sum(x => x.RefundBalanceSum ?? 0),
                    UserStatistics = items.GroupBy(x => x.Username)
                        .Select(g => new
                        {
                            Username = g.Key,
                            FullName = g.First().FullName,
                            RecordCount = g.Count(),
                            TotalAmount = g.Sum(x => x.RefundBalanceSum ?? 0)
                        })
                        .OrderByDescending(x => x.TotalAmount),
                    DailyStatistics = items.GroupBy(x => x.InputDate?.Date)
                        .Select(g => new
                        {
                            Date = g.Key,
                            RecordCount = g.Count(),
                            TotalAmount = g.Sum(x => x.RefundBalanceSum ?? 0)
                        })
                        .OrderBy(x => x.Date)
                };
                
                return report;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取统计报表失败，开始日期: {StartDate}, 结束日期: {EndDate}", startDate, endDate);
                throw;
            }
        }

        /// <summary>
        /// 将实体映射为响应对象
        /// </summary>
        private static RefundAcctResponse MapToResponse(RefundAcct refundAcct)
        {
            return new RefundAcctResponse
            {
                Id = refundAcct.Id,
                InputDate = refundAcct.InputDate,
                Username = refundAcct.Username,
                FullName = refundAcct.FullName,
                AcctId = refundAcct.AcctId,
                RefundBalanceSum = refundAcct.RefundBalanceSum
            };
        }
    }
}